package p03_bean生命周期;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * bean后处理器，就是一种模板方法模式的经典实现
 * 将不变的代码写死(生命周期各个节点是固定的),变化的代码抽象出来(在生命周期的各个节点回调哪些方法，是变化的)
 */
@Slf4j
public class _2_模板方法模式 {
    public static void main(String[] args) {
        /**
         * 给某个结点前后进行扩展，利用的是设计模式:模板方法模式
         *      将不变的写死，将变化的抽象成接口
         * 代码见TemplateMethod
         *      我们将自定义的扩展交给beanPostProcessors数组，TemplateMethod就会一一执行我们的自定义扩展
         */
        TemplateMethod templateMethod = new TemplateMethod();
        //添加两个后处理器
        templateMethod.beanPostProcessors.add(bean->{log.info("初始化" + bean + "之前执行");});
        templateMethod.beanPostProcessors.add(bean->{log.info("初始化" + bean + "之后执行");});
        //getBean会回调我们添加的后处理器的init方法
        templateMethod.getBean();
    }

    static class TemplateMethod {
        private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

        public Object getBean() {
            /**
             * 这里模拟了构造一个bean给过程中，在不同的生命周期阶段调用不同的回调函数
             */
            Object bean = new TestBean();
            log.info("构造" + bean);
            log.info("依赖注入" + bean);
            //扩展的初始化方法，这里是抽象的
            for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
                beanPostProcessor.init(bean);
            }
            log.info("销毁" + bean);
            return bean;
        }

        /**
         * 模拟了一个后处理器接口
         */
        interface BeanPostProcessor {
            void init(Object bean);
        }
    }


}
